﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LayoutController.cs" company="ecblog.codeplex.com">
//   emrecoskun.net - ibrahimatay.com
// </copyright>
// <summary>
//   The layout controller
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace EcBlog.Areas.Admin.Controllers
{
    using System;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Linq;
    using System.Web.Mvc;

    using EcBlog.Data;
    using EcBlog.Models;
    using EcBlog.Properties;

    using Elmah;

    using Telerik.Web.Mvc;
    using Telerik.Web.Mvc.Extensions;

    /// <summary>
    /// The layout controller
    /// </summary>
    [Export, PartCreationPolicy(CreationPolicy.NonShared)]
#if !(DEBUG)
    [Filters.Authorize(PortalRole.Admin)]
#endif
    public class LayoutController : Controller
    {
        #region ctor
        private readonly IEcUnitOfWork unitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="LayoutController"/> class.
        /// </summary>
        /// <param name="unitOfWork">The unit of work.</param>
        [ImportingConstructor]
        public LayoutController(IEcUnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        } 
        #endregion

        #region Core Action Methods
        /// <summary>
        /// Gets the index view.
        /// </summary>
        /// <returns>The index view.</returns>
        public ActionResult Index()
        {
            return this.View();
        } 
        #endregion 

        #region AJAX Layout Master Grid Action Methods
        /// <summary>
        /// Gets the layout list.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <returns>The index view</returns>
        [GridAction(EnableCustomBinding = true)]
        public ActionResult LayoutList(GridCommand command = null)
        {
            if (command == null)
            {
                command = new GridCommand();
            }

            var list = this.unitOfWork.LayoutRepository.Get(); 
            return this.View(list.ToGridModel(command.Page, command.PageSize, command.SortDescriptors, command.FilterDescriptors, command.GroupDescriptors)); 
        }

        /// <summary>
        /// Inserts the specified layout.
        /// </summary>
        /// <param name="layout">The layout.</param>
        /// <param name="command">The command.</param>
        /// <returns>The index view</returns>
        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult Insert(Layout layout, GridCommand command = null)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    var defaultLayoutName = this.unitOfWork.SiteSettingRepository[SiteSettingKey.DefaultLayoutName];

                    if (layout.Name == defaultLayoutName)
                    { 
                        this.Response.StatusCode = 500;
                        this.Response.AppendHeader("message", string.Format(ModelLocalization.DefaultLayoutDeleteError, layout.Name));
                    }
                    else
                    {
                        this.unitOfWork.LayoutRepository.Create(layout);
                        this.unitOfWork.Save();
                        CreateFiles(layout);
                    }
                }
                catch (Exception e)
                {
                    ErrorSignal.FromCurrentContext().Raise(e);
                    this.Response.StatusCode = 500;
                    this.Response.AppendHeader(
                        "message", string.Format(ModelLocalization.SaveUnitOfWorkError, layout.Name, e.Message));
                }
            }

            return this.LayoutList(command);
        }

        /// <summary>
        /// Edits the specified layout.
        /// </summary>
        /// <param name="layout">The layout.</param>
        /// <param name="command">The command.</param>
        /// <returns>The index view.</returns>
        [HttpPost, GridAction]
        public ActionResult Edit(Layout layout, GridCommand command = null)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    var defaultLayoutName = this.unitOfWork.SiteSettingRepository[SiteSettingKey.DefaultLayoutName];
                    if (layout.Name == defaultLayoutName)
                    {
                        this.Response.StatusCode = 500;
                        this.Response.AppendHeader(
                            "message", string.Format(ModelLocalization.DefaultLayoutDeleteError, layout.Name));
                    }
                    else
                    {
                        this.unitOfWork.LayoutRepository.Update(layout);
                        this.unitOfWork.Save();
                        CreateFiles(layout);
                    }
                }
                catch (Exception e)
                {
                    ErrorSignal.FromCurrentContext().Raise(e);
                    this.Response.StatusCode = 500;
                    this.Response.AppendHeader(
                        "message", string.Format(ModelLocalization.SaveUnitOfWorkError, layout.Name, e.Message));
                }
            }

            return this.LayoutList(command);
        }

        /// <summary>
        /// Deletes the specified layout id.
        /// </summary>
        /// <param name="layoutId">The layout id.</param>
        /// <param name="command">The command.</param>
        /// <returns>The index view.</returns>
        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult Delete(int layoutId, GridCommand command = null)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    var defaultLayoutName = this.unitOfWork.SiteSettingRepository[SiteSettingKey.DefaultLayoutName];
                    var layot = this.unitOfWork.LayoutRepository.GetById(layoutId);
                    var layoutCount = this.unitOfWork.LayoutRepository.Get().Count();

                    if (layot.Name == defaultLayoutName && layoutCount > 1)
                    {
                        // TODO change error message
                        this.Response.StatusCode = 500;
                        this.Response.AppendHeader("message", string.Format(ModelLocalization.DeleteSubItemFirst, layot.Name));
                    }
                    else
                    {
                        this.unitOfWork.LayoutRepository.Delete(layot);
                        this.unitOfWork.Save();
                    }
                }
                catch (Exception e)
                {
                    ErrorSignal.FromCurrentContext().Raise(e);
                    this.Response.StatusCode = 500;
                    this.Response.AppendHeader(
                        "message", string.Format(ModelLocalization.SaveUnitOfWorkError, layoutId, e.Message));
                }
            }

            return this.LayoutList(command);
        }

        #endregion      

        #region AJAX Support Methods

        /// <summary>
        /// Checks the name of the duplicate layout.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="layoutId">The layout id.</param>
        /// <returns>The index view</returns>
        public ActionResult CheckDuplicateLayoutName(string name, long layoutId)
        {
            var validateTitle =
                !this.unitOfWork.LayoutRepository.Get().Any(
                    c => c.LayoutId != layoutId && c.Name.ToLower() == name.ToLower());
            return this.Json(validateTitle, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Checks the duplicate layout path.
        /// </summary>
        /// <param name="layoutPath">The layout path.</param>
        /// <param name="layoutId">The layout id.</param>
        /// <returns>The index view</returns>
        public ActionResult CheckDuplicateLayoutPath(string layoutPath, long layoutId)
        {
            var validateTitle =
                !this.unitOfWork.LayoutRepository.Get().Any(
                    c => c.LayoutId != layoutId && c.LayoutPath.ToLower() == layoutPath.ToLower());
            return this.Json(validateTitle, JsonRequestBehavior.AllowGet);
        }
        #endregion

        #region disbose

        /// <summary>
        /// Releases unmanaged resources and optionally releases managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            this.unitOfWork.Dispose();
            base.Dispose(disposing);
        }

        #endregion

        #region Support Methods
        private static void CreateFiles(Layout layout)
        {
            var layoutfile = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, layout.LayoutPath.Replace(@"~/", string.Empty));

            var layoutpath = Path.GetDirectoryName(layoutfile);
            if (layoutpath == null)
            {
                return;
            }

            if (!Directory.Exists(layoutpath))
            {
                Directory.CreateDirectory(layoutpath);
            }

            if (!System.IO.File.Exists(layoutfile))
            {
                System.IO.File.AppendAllText(layoutfile, string.Empty);
            }
        }
        #endregion
    }
}
